home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_546 / wblink / source / wblink.c next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  305 lines

  1.  
  2. /*************************************************************************/
  3. /*                 WBLink V1.00                 */
  4. /*                                     */
  5. /* WBLink is Copyright 1991 by Dave Schreiber.    All Rights Reserved     */
  6. /*                                     */
  7. /* WBLink puts an AppIcon on the Workbench.  When a file is dropped onto */
  8. /* the icon, a link to that file is generated.                 */
  9. /*************************************************************************/
  10.  
  11.  
  12. #include <exec/types.h>
  13. #include <exec/exec.h>
  14. #include <intuition/intuition.h>
  15. #include <workbench/startup.h>
  16. #include <workbench/workbench.h>
  17. #include <dos/dos.h>
  18.  
  19. #include <proto/wb.h>
  20. #include <proto/intuition.h>
  21. #include <proto/exec.h>
  22. #include <proto/dos.h>
  23. #include <proto/icon.h>
  24.  
  25. #include "WBLink.h"
  26.  
  27. /* Function prototypes*/
  28. void _main();
  29. BOOL GetLinkFilename(char *src,char *dest);
  30. void MakeName(char *src,char *dest,int c);
  31. void FindOrig(char *src,char *dest);
  32. void cleanup(UWORD err);
  33.  
  34. /* Global variables */
  35. struct Library *WorkbenchBase=NULL;
  36. struct Library *IconBase=NULL;
  37. struct Library *IntuitionBase=NULL;
  38. struct Port *port=NULL;
  39. struct AppIcon *appIcon=NULL;
  40.  
  41. /*The version string*/
  42. char *version="$VER: WBLink V1.00 (4.9.91)";
  43.  
  44. void _main()
  45. {
  46.    struct AppMessage *mesg;
  47.    char dest[40],*src,temp[140];
  48.    BPTR oldDir,fileLock;
  49.    struct DiskObject *diskObj;
  50.  
  51.    BOOL abort=FALSE;
  52.    BOOL status;
  53.    BOOL isDir=FALSE;
  54.    UBYTE c;
  55.  
  56.    /* Open libraries */
  57.    WorkbenchBase=OpenLibrary("workbench.library",0L);
  58.    if(WorkbenchBase==NULL)
  59.       cleanup(50);
  60.  
  61.    IconBase=OpenLibrary("icon.library",0L);
  62.    if(IconBase==NULL)
  63.       cleanup(75);
  64.  
  65.    IntuitionBase=OpenLibrary("intuition.library",0L);
  66.    if(IntuitionBase==NULL)
  67.       cleanup(85);
  68.  
  69.    /* Create a port for Workbench to use to communicate with us */
  70.    port=CreatePort("",0);
  71.    if(port==NULL)
  72.       cleanup(100);
  73.  
  74.    /* Create the application icon */
  75.    appIcon = AddAppIcon(1,1,"WBLink",port,NULL,&iconObj,TAG_DONE,NULL);
  76.  
  77.    if(appIcon==NULL)
  78.       cleanup(300);
  79.  
  80.    /* Loop until the user asks to quit */
  81.    while(!abort)
  82.    {
  83.       /* Wait for a message from Workbench */
  84.       WaitPort(port);
  85.  
  86.       /* Get the message */
  87.       mesg=(struct AppMessage *)GetMsg(port);
  88.  
  89.       /* If am_NumArgs != 0, it means one or more icons were dropped on */
  90.       /* the AppIcon */
  91.       if(mesg->am_NumArgs!=0)
  92.       {
  93.      /* Loop for each file */
  94.      for(c=0;c<mesg->am_NumArgs;c++)
  95.      {
  96.         /* Check to see if this is a drawer */
  97.         if(mesg->am_ArgList[c].wa_Name[0]==0 &&
  98.           mesg->am_ArgList[c].wa_Lock != NULL)
  99.         {
  100.            isDir=TRUE;
  101.  
  102.            /* If it is a drawer, we didn't get the name from Workbench*/
  103.            /* So we need to get the name from the lock instead*/
  104.            if(!NameFromLock(mesg->am_ArgList[c].wa_Lock,temp,139))
  105.           continue;
  106.  
  107.            /* The name we get is the full path name.  This function*/
  108.            /* call will leave us with just the directory*/
  109.            src=FilePart(temp);
  110.         }
  111.         else
  112.         {
  113.            /* If it is a file, just copy the filename */
  114.            strcpy(src,mesg->am_ArgList[c].wa_Name);
  115.            isDir=FALSE;
  116.         }
  117.  
  118.         /* Move to the file's directory*/
  119.         if(isDir)
  120.            /* If we got a drawer, the lock is to the directory */
  121.            /* itself.  To get the directory that the drawer is in, */
  122.            /* we need to use ParentDir() */
  123.            oldDir=CurrentDir(ParentDir(mesg->am_ArgList[c].wa_Lock));
  124.         else
  125.            oldDir=CurrentDir(mesg->am_ArgList[c].wa_Lock);
  126.  
  127.         /* Get the destination filename (i.e. foo -> Link_to_foo ) */
  128.         if(GetLinkFilename(src,dest))
  129.         {
  130.            /* Get a lock on the file that was given */
  131.            if(isDir)
  132.           fileLock=mesg->am_ArgList[c].wa_Lock;
  133.            else
  134.           fileLock=Lock(src,SHARED_LOCK);
  135.  
  136.            /* If we got the lock, make the link */
  137.            if(fileLock!=NULL)
  138.            {
  139.           status=MakeLink(dest,fileLock,FALSE);
  140.           if(!isDir)
  141.              UnLock(fileLock);
  142.  
  143.           /* If we managed to make the link, copy (NOT link) the */
  144.           /* source's icon */
  145.           if(status)
  146.           {
  147.              /* Get the source file's icon */
  148.              diskObj=GetDiskObject(src);
  149.  
  150.              if(diskObj!=NULL)
  151.              {
  152.             /* Reset the icon's position*/
  153.             diskObj->do_CurrentY=NO_ICON_POSITION;
  154.             diskObj->do_CurrentX=NO_ICON_POSITION;
  155.  
  156.             /* Store the icon as the destination's icon */
  157.             PutDiskObject(dest,diskObj);
  158.  
  159.             /* Free the disk object's memory */
  160.             FreeDiskObject(diskObj);
  161.              }
  162.           }
  163.           else
  164.              EasyRequest(NULL,&erError2,NULL,
  165.                  "Couldn't create the link",dest);
  166.            }
  167.            else
  168.           EasyRequest(NULL,&erError3,NULL,"Couldn't open",
  169.                   src,"for linking");
  170.         }
  171.         else
  172.            EasyRequest(NULL,&erError2,NULL,"Couldn't create",
  173.                "a filename for the link");
  174.         /* Restore the old directory */
  175.         CurrentDir(oldDir);
  176.      }
  177.       }
  178.       else  /* If am_NumArgs==0, the user double clicked on the icon */
  179.         /* So put up the About... requestor, and quit if the user */
  180.         /* clicks on the "Quit WBLink" button  */
  181.      abort=(EasyRequestArgs(NULL,&erAboutWBLink,NULL,NULL)==1);
  182.  
  183.       /* Reply to the message */
  184.       ReplyMsg((struct Message *)mesg);
  185.    }
  186.  
  187.    /* We're done, so exit */
  188.    cleanup(0);
  189. }
  190.  
  191.  
  192. /* Create a link filename (i.e. foo -> Link_to_foo ) */
  193. BOOL GetLinkFilename(char *src,char *dest)
  194. {
  195.    UWORD c;
  196.    BPTR lock=1;
  197.    char realSrc[40];
  198.  
  199.    /* Strip away the link portion of the filename, leaving the original */
  200.    /* filename */
  201.    FindOrig(src,realSrc);
  202.  
  203.    /* Loop until we get a unused filename slot */
  204.    for(c=1;c<1000 && lock!=NULL;c++)
  205.    {
  206.       /* Create a filename (e.g. Link_22_to_HelloWorld) */
  207.       MakeName(realSrc,dest,c);
  208.  
  209.       /* See if it exists */
  210.       lock=Lock(dest,SHARED_LOCK);
  211.  
  212.       /* If the lock was successful, unlock the file */
  213.       if(lock!=NULL)
  214.      UnLock(lock);
  215.    }
  216.  
  217.    /* Return TRUE if the destination file name is <26 characters ( so */
  218.    /* that the filename + .info won't exceed the Amiga's 30 character */
  219.    /* filename limit) and if c<1000 (1000 is the upper limit on the   */
  220.    /* number of files that will be created; it's in place as a safe-  */
  221.    /* guard, to keep the above loop from becoming infinite)          */
  222.    return((strlen(dest)<=25) && !(c==1000));
  223. }
  224.  
  225. /* Add the link prefix to the given filename */
  226. void MakeName(char *src,char *dest,int c)
  227. {
  228.    /* For c==1, don't use a number (e.g. foo -> Link_to_foo) */
  229.    if(c==1)
  230.    {
  231.       strcpy(dest,"Link_to_");
  232.       strcat(dest,src);
  233.    }
  234.    /* For all others, include the given number (e.g. for c==2, foo -> */
  235.    /* Link_2_to_foo */
  236.    else
  237.    {
  238.       strcpy(dest,"Link_");
  239.       stci_d(&dest[5],c);
  240.       strcat(dest,"_to_");
  241.       strcat(dest,src);
  242.    }
  243. }
  244.  
  245.  
  246. /* Strip the link information from the filename (i.e. convert */
  247. /* Link_22_to_foobar into foobar) to make the 'original' filename */
  248. void FindOrig(char *src,char *dest)
  249. {
  250.    UBYTE c,numUS;
  251.  
  252.    if((strnicmp(src,"link_",5))==0)
  253.       if((strnicmp(src,"link_to_",8))==0)
  254.      /* This handles Link_to_<filename> */
  255.      strcpy(dest,&src[8]);
  256.       else
  257.       {
  258.      /* This handles Link_<number>_to_<filename> */
  259.      /* Move past two underscores (there are two after the <number>) */
  260.      for(c=5,numUS=0;c<30;c++)
  261.      {
  262.         if(src[c]=='_')
  263.            numUS++;
  264.         if(numUS==2)
  265.         {
  266.            /* Whatever is left is the original filename */
  267.            strcpy(dest,&src[c+1]);
  268.            return;
  269.         }
  270.      }
  271.      /*If we couldn't find two underscores, just copy the whole thing*/
  272.      strcpy(dest,src);
  273.       }
  274.    else  /*This is just a regular filename, so copy the whole thing */
  275.       strcpy(dest,src);
  276. }
  277.  
  278. /* This frees allocated resources */
  279. void cleanup(UWORD err)
  280. {
  281.    /* The AppIcon */
  282.    if(appIcon!=NULL)
  283.       RemoveAppIcon(appIcon);
  284.  
  285.    /* The port */
  286.    if(port!=NULL)
  287.       DeletePort(port);
  288.  
  289.  
  290.    /* The libraries */
  291.    if(WorkbenchBase!=NULL)
  292.       CloseLibrary(WorkbenchBase);
  293.  
  294.    if(IconBase!=NULL)
  295.       CloseLibrary(IconBase);
  296.  
  297.    if(IntuitionBase!=NULL)
  298.       CloseLibrary(IntuitionBase);
  299.  
  300.    /* Exit the program, using the specified error code */
  301.    exit(err);
  302. }
  303.  
  304.  
  305.